<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>商品列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片 -->
    <el-card>
      <el-row>
        <el-col>
          <el-button type="primary"
                     @click="showAddCateDialog">添加分类</el-button>
        </el-col>
      </el-row>
    </el-card>

    <!-- 分类表格 -->
    <tree-table :data="cateList"
                :columns="cols"
                :selection-type="false"
                :expand-type="false"
                show-index
                index-text="#"
                border
                :show-row-hover="false">
      <!-- 是否有效 列 模板 -->
      <template slot="isOk"
                slot-scope="scope">
        <i v-if="scope.row.cat_deleted == false"
           class="el-icon-success"
           style="color: lightGreen"></i>
        <i v-else
           class="el-icon-error"
           style="color: hotpink"></i>
      </template>
      <!-- 排序 列 模板 -->
      <template slot="order"
                slot-scope="scope">
        <el-tag v-if="scope.row.cat_level == 0">一级菜单</el-tag>
        <el-tag type="success"
                v-else-if="scope.row.cat_level == 1">二级菜单</el-tag>
        <el-tag type="danger"
                v-else>三级菜单</el-tag>
      </template>
      <!-- 操作列 -->
      <template slot="opt">
        <el-button type="primary"
                   icon="el-icon-edit"
                   size="mini">编辑</el-button>
        <el-button type="danger"
                   icon="el-icon-delete"
                   size="mini">删除</el-button>
      </template>
    </tree-table>

    <!-- 分页区域 -->
    <el-pagination @size-change="handleSizeChange"
                   @current-change="handleCurrentChange"
                   :current-page="queryData.pagenum"
                   :page-sizes="[3, 5, 10, 20]"
                   :page-size="queryData.pagesize"
                   layout="total, sizes, prev, pager, next, jumper"
                   :total="total"
                   class="treeTable">
    </el-pagination>

    <!-- 对话框 -->
    <el-dialog title="添加分类"
               :visible.sync="isAddCateDialogShow"
               width="50%"
               @close="resetCateForm">
      <!--添加分类的表单 内容区域 -->
      <el-form ref="formAddCate"
               :model="addCateForm"
               :rules="addCateRules"
               label-width="100px">
        <!-- 表单项目 -->
        <el-form-item label="分类名称"
                      prop="cat_name">
          <!-- 文本框 -->
          <el-input v-model="addCateForm.cat_name"></el-input>
        </el-form-item>
        <!-- 表单项 父级分类 -->
        <el-form-item label="父级分类：">
          <el-cascader v-model="selectedCates"
                       clearable
                       :options="addCateList"
                       :props="{checkStrictly:true,expandTrigger: 'hover',value: 'cat_id',label: 'cat_name',children: 'children',}"
                       @change="handleChange"></el-cascader>
        </el-form-item>
      </el-form>
      <!-- 按钮区域 -->
      <span slot="footer"
            class="dialog-footer">
        <el-button @click="isAddCateDialogShow = false">取 消</el-button>
        <el-button type="primary"
                   @click="addCate">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // 钩子函数（可以看做vue组件的入口函数）
  created () {
    this.getCateList()
  },
  data () {
    return {
      // 查询参数对象
      queryData: {
        type: 3,
        pagenum: 1,
        pagesize: 5
      },
      // 商品分类数组
      cateList: [],
      // 总数据行数
      total: 0,
      // 表格列定义
      cols: [
        {
          label: '分类名',
          prop: 'cat_name'
        },
        {
          label: '是否有效',
          prop: 'cat_deleted',
          type: 'template', // 设置模板列
          template: 'isOk' // 指定模板名字
        },
        {
          label: '排序',
          prop: 'cat_level',
          type: 'template', // 设置模板列
          template: 'order' // 指定模板名字
        },
        {
          label: '操作',
          type: 'template', // 设置模板列
          template: 'opt' // 指定模板名字
        }
      ],
      // 控制添加分类 对话框 显示隐藏开关
      isAddCateDialogShow: false,
      // 添加类别用的表单数据对象 (数据对象的属性保持和接口要求参数一致)
      addCateForm: {
        cat_name: '', // 分类名
        cat_level: 0, // 分类层级
        cat_pid: 0 // 分类父id
      },
      // 添加类别用的规则对象
      addCateRules: {
        cat_name: [
          {
            required: true,
            message: '请输入分类名称',
            trigger: 'blur'
          },
          {
            min: 2,
            max: 7,
            message: '长度在2到7个字符',
            trigger: 'blur'
          }
        ]
      },
      // 添加分类时 父分类下拉框数据数组
      addCateList: [],
      // 添加分类时 选中的父分类的id
      selectedCates: []
    }
  },

  methods: {
    // 获取分类列表数据
    async getCateList () {
      const { data: resData } = await this.$http.get('categories', {
        params: this.queryData
      })
      // 判断是否有问题
      if (resData.meta.status !== 200) { return this.$message.error(resData.meta.msg) }
      // 如果成功
      // 保存总数据行数
      this.total = resData.data.total
      // 保存 分类数组
      this.cateList = resData.data.result
    },
    // 页容量改变事件函数
    handleSizeChange (newSize) {
      // 修改 查询参数中 的新页容量
      this.queryData.pagesize = newSize
      // 重新查询分页数据
      this.getCateList()
    },
    // 页码发生改变事件函数
    handleCurrentChange (curPageIndex) {
      // 修改 查询参数中的当前页码
      this.queryData.pagenum = curPageIndex
      // 重新查询分页数据
      this.getCateList()
    },
    // 显示新增 分类对话框 并加载父级 分类数据
    async showAddCateDialog () {
      // 显示新增分类对话框
      this.isAddCateDialogShow = true
      // 加载父级分类数据
      const { data: resData } = await this.$http.get('categories', {
        params: {
          type: 2
        }
      })
      // 如果加载失败
      if (resData.meta.status !== 200) { return this.$message.error(resData.meta.msg) }
      // 如果加载成功
      this.addCateList = resData.data
    },
    // 新增分类对话框中 父级分类下拉框 改变事件函数
    handleChange () {
      // 每次 分类选项 发生改变时,更新 表单数据
      // 如果 没有选中 父分类,说明添加的是 [一级分类]
      if (this.selectedCates.length === 0) {
        this.addCateForm.cat_pid = 0
        this.addCateForm.cat_level = 0
        // 如果 选择了 1个父分类,说明添加的是 [二级分类]
      } else if (this.selectedCates.length === 1) {
        this.addCateForm.cat_pid = this.selectedCates[0]
        this.addCateForm.cat_level = 1
        // 如果 选择了 2个父分类,说明添加的是 [三级分类]
      } else if (this.selectedCates.length === 2) {
        this.addCateForm.cat_pid = this.selectedCates[1]
        this.addCateForm.cat_level = 2
      }
    },
    // 重置 新增分类 表单
    resetCateForm () {
      // 清空文本框(双向数据绑定)
      this.addCateForm.cat_name = ''
      // 重置 表单数据 的 级别 和父分类的 id
      this.addCateForm.cat_level = ''
      this.addCateForm.cat_pid = ''
      // 重置 父分类下拉框
      this.selectedCates = []
    },
    // 新增分类 确认按钮函数
    addCate () {
      // 调用表单对象 校验
      this.$refs.formAddCate.validate(async result => {
        // 如果校验失败
        if (!result) return
        // 发送异步请求 将表单数据 提交给 接口
        const { data: resData } = await this.$http.post('categories', this.addCateForm)
        if (resData.meta.status !== 201) {
          return this.$message.error(resData.meta.msg)
        }
        // 如果成功
        // 关闭对话框
        this.isAddCateDialogShow = false
        // 更新 分类表格
        this.$message.success(resData.meta.msg)
        // 优化请求方案
        // 如果 当前页码 是最后一页,则调用 getCateList 重新请求当前页数据
        const totalPage = Math.ceil(this.total / this.queryData.pagesize)
        if (this.queryData.pagenum === totalPage) {
          this.getCateList()
        } else {
          // 如果 当前页码不是最后一页,则 不需要重复请求当前页数据
          //      只需修改 total实现页码重新计算
          //      注意: 只有添加的是1级分类时,才需要 total+1
          if (this.addCateForm.cat_level === 0) this.total++
          // 添加的是 2级3级菜单,则 重新请求当前页数据
          else this.resetCateForm()
        }
        // 重置 表单数据
        this.resetCateForm()
      })
    }
    //
  }
}
</script>

<style lang="less" scoped>
.treeTable {
  margin-top: 15px;
}
.el-cascader {
  width: 100%;
}
</style>
